package com.ywb.edugui.utils;

/**
 * @Author ywb
 * 简化版的雪花算法，根据时间戳、机器码和序列生成一串字符
 */
public class MySnowflakeIdWorker {
    /** 开始时间戳 （20201-01-01）*/
    private static long startTimeStamp = 1577808000000L;
    /** 上次使用的时间戳*/
    private static long lastTimeStamp = -1l;
    /** 时间戳的序列*/
    private static long sequence = 0l;
    /** 自定义的机器码*/
    private static long wordId = 1;
    /** 序列占12位 */
    private static final long sequenceBits = 12L;
    /** 机器码占10位, 左移12位 */
    private static final long wordIdBits = 10L;
    private static final long workerIdLeftShift = sequenceBits;
    /** 时间戳左移17位*/
    private static final long timestampLeftShift = workerIdLeftShift + wordIdBits;

    /** 机器ID默认为0,当不同的机器上需要修改的时候调用这个参数即可*/
    public static void setWordId(long id){
        wordId = id;
    }

    /**
     * 根据当前时间戳-开始时间戳|机器码|序列生成19位的连续递增不重复的id
     * @return
     */
    public static synchronized String nextId(){
        long timeStamp = System.currentTimeMillis();
//        当这次使用的时间和上次时间相等时,序列就递增,否则序列重置为0
        if (timeStamp == lastTimeStamp){
            sequence += 1;
        } else{
          sequence = 0;
        }
//        将上次的时间戳重置为当前时间戳
        lastTimeStamp = timeStamp;

//        System.out.println(getByte(timeStamp - startTimeStamp));
//        System.out.println(getByte((timeStamp - startTimeStamp) << timestampLeftShift));
//        System.out.println(getByte(13 | (timeStamp - startTimeStamp) << timestampLeftShift));
//        System.out.println(getByte(wordId ));

        return String.valueOf((timeStamp - startTimeStamp) << timestampLeftShift
        | wordId << workerIdLeftShift
        | sequence);
    }

    /** 测试二进制值*/
    public static String getByte(long val){
        String b = "";
        int i = 0;
        while(val / 2 != 0){
            b += String.valueOf (val % 2);
            val = val / 2;
        }
        return b;
    }
}
